﻿/* Copyright (C) Siemens AG, 2012. All Rights Reserved.
 * Author: Roland Eckl, Corporate Technology
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;


namespace RVM.Infrastructure.Communication.WCF
{
    /// <summary>
    /// ExtendedInstanceProvider is used to pass arbitrary arguments to a service's constructor.
    /// </summary>
    public class ExtendedInstanceProvider : IInstanceProvider, IContractBehavior
    {
        #region Private Members

        /// <summary>
        /// Arguments to pass to constructor when an instance is requested.
        /// </summary>
        private readonly object[] _arguments;

        /// <summary>
        /// Type of service to create on request.
        /// </summary>
        private readonly Type _serviceType;

        #endregion

        #region Constructors

        /// <summary>
        /// Default constrcutor.
        /// </summary>
        /// <param name="serviceType">Type of service</param>
        /// <param name="arguments">Arbitrary arguments</param>
        public ExtendedInstanceProvider(Type serviceType, params object[] arguments)
        {
            _serviceType = serviceType;
            _arguments = arguments;
        }

        #endregion

        #region IInstanceProvider Members

        /// <summary>
        /// Creates a new service instance on request.
        /// </summary>
        /// <param name="instanceContext"></param>
        /// <param name="message"></param>
        /// <returns>New instance of type _serviceType</returns>
        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return GetInstance(instanceContext);
        }

        /// <summary>
        /// Creates a new service instance on request.
        /// </summary>
        /// <param name="instanceContext"></param>
        /// <returns>New instance of type _serviceType</returns>
        public object GetInstance(InstanceContext instanceContext)
        {
            return Activator.CreateInstance(_serviceType, _arguments);
        }

        /// <summary>
        /// Reales a dedicated service instance.
        /// </summary>
        /// <param name="instanceContext"></param>
        /// <param name="instance"></param>
        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
        }

        #endregion

        #region IContractBehavior Members

        /// <summary>
        /// Unused, but implemented to fulfill IContractBehavior interface.
        /// </summary>
        /// <param name="contractDescription"></param>
        /// <param name="endpoint"></param>
        /// <param name="bindingParameters"></param>
        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        /// <summary>
        /// Unused, but implemented to fulfill IContractBehavior interface.
        /// </summary>
        /// <param name="contractDescription"></param>
        /// <param name="endpoint"></param>
        /// <param name="clientRuntime"></param>
        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        /// <summary>
        /// Sets this ExtendedInstanceProvider for the dispatching runtime.
        /// </summary>
        /// <param name="contractDescription"></param>
        /// <param name="endpoint"></param>
        /// <param name="dispatchRuntime"></param>
        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            dispatchRuntime.InstanceProvider = this;
        }

        /// <summary>
        /// Unused, but implemented to fulfill IContractBehavior interface.
        /// </summary>
        /// <param name="contractDescription"></param>
        /// <param name="endpoint"></param>
        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }

        #endregion
    } 

}
